package com.vshop.platform.system.crud.dao;

import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vshop.platform.system.domain.entity.SysUserRole;
import com.vshop.platform.system.crud.mapper.SysUserRoleMapper;
import com.vshop.platform.system.domain.param.SysUserParam;
import org.springframework.stereotype.Repository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

import static com.mybatisflex.core.query.QueryMethods.select;
import static com.vshop.platform.system.domain.entity.table.SysDeptTableDef.SysDeptTable;
import static com.vshop.platform.system.domain.entity.table.SysRoleTableDef.SysRoleTable;
import static com.vshop.platform.system.domain.entity.table.SysUserRoleTableDef.SysUserRoleTable;
import static com.vshop.platform.system.domain.entity.table.SysUserTableDef.SysUserTable;


/**
 * 用户和角色关联表 服务层实现。
 *
 * @author vshop
 * @since 2024-11-18
 */
@RequiredArgsConstructor
@Slf4j
@Repository
public class SysUserRoleDao extends ServiceImpl<SysUserRoleMapper, SysUserRole> {

    /**
     * 根据条件分页查询已分配用户角色分页列表
     */
    public QueryWrapper pageAllocatedUserQueryWrapper(SysUserParam param) {
  /* select distinct u.user_id, u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time
        from sys_user u
        left join sys_dept d on u.dept_id = d.dept_id
        left join sys_user_role ur on u.user_id = ur.user_id
        left join sys_role r on r.role_id = ur.role_id
        where u.del_flag = '0' and r.role_id = #{roleId}
	    <if test="userName != null and userName != ''">
            AND u.user_name like concat('%', #{userName}, '%')
		</if>
		<if test="phonenumber != null and phonenumber != ''">
            AND u.phonenumber like concat('%', #{phonenumber}, '%')
		</if>
		<!-- 数据范围过滤 -->
            ${params.dataScope}*/
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(QueryMethods.distinct(SysUserTable.UserId, SysUserTable.TenantId, SysUserTable.DeptId,
                        SysUserTable.UserName, SysUserTable.NickName, SysUserTable.UserType, SysUserTable.Email,
                        SysUserTable.PhoneNumber, SysUserTable.Status, SysUserTable.CreateTime, SysDeptTable.DeptName))
                .from(SysUserTable.as("u"))
                .leftJoin(SysDeptTable).as("d").on(SysDeptTable.DeptId.eq(SysUserTable.DeptId))
                .leftJoin(SysUserRoleTable).as("ur").on(SysUserRoleTable.UserId.eq(SysUserTable.UserId))
                .leftJoin(SysRoleTable).as("r").on(SysRoleTable.RoleId.eq(SysUserRoleTable.RoleId))
                .where(SysUserTable.DeleteFlag.eq(0))
                .and(SysRoleTable.RoleId.eq(param.getRoleId()));
        queryWrapper.and(SysUserTable.UserName.like(param.getUserName()))
                .and(SysUserTable.PhoneNumber.like(param.getPhoneNumber()));
        log.info("查询条件：{}", queryWrapper.toSQL());
        return queryWrapper;
    }

    /**
     * 根据条件分页查询未分配用户角色分页列表
     */
    public QueryWrapper pageUnAllocatedUserQueryWrapper(SysUserParam param) {
         /*select distinct u.user_id,  u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time
        from sys_user u
        left join sys_dept d on u.dept_id = d.dept_id
        left join sys_user_role ur on u.user_id = ur.user_id
        left join sys_role r on r.role_id = ur.role_id
        where u.del_flag = '0' and (r.role_id != #{roleId} or r.role_id IS NULL)
        and u.user_id not in (select u.user_id from sys_user u inner join sys_user_role ur on u.user_id = ur.user_id and ur.role_id = #{roleId})
	    <if test="userName != null and userName != ''">
            AND u.user_name like concat('%', #{userName}, '%')
		</if>
		<if test="phonenumber != null and phonenumber != ''">
            AND u.phonenumber like concat('%', #{phonenumber}, '%')
		</if>
		<!-- 数据范围过滤 -->
            ${params.dataScope}*/
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(QueryMethods.distinct(SysUserTable.UserId, SysUserTable.TenantId, SysUserTable.DeptId,
                        SysUserTable.UserName, SysUserTable.NickName, SysUserTable.UserType, SysUserTable.Email,
                        SysUserTable.PhoneNumber, SysUserTable.Status, SysUserTable.CreateTime, SysDeptTable.DeptName,
                        SysRoleTable.RoleName))
                .from(SysUserTable.as("u"))
                .leftJoin(SysDeptTable).as("d").on(SysDeptTable.DeptId.eq(SysUserTable.DeptId))
                .leftJoin(SysUserRoleTable).as("ur").on(SysUserRoleTable.UserId.eq(SysUserTable.UserId))
                .leftJoin(SysRoleTable).as("r").on(SysRoleTable.RoleId.eq(SysUserRoleTable.RoleId))
                .where(SysUserTable.DeleteFlag.eq(0))
                .and(SysUserTable.Status.eq("0"))
                .and(SysRoleTable.RoleId.ne(param.getRoleId()).or(SysRoleTable.RoleId.isNull()))
                .and(SysUserTable.UserId.notIn(
                        select(SysUserTable.UserId).from(SysUserTable.as("u"))
                                .innerJoin(SysUserRoleTable).as("ur")
                                .on(SysUserRoleTable.UserId.eq(SysUserTable.UserId)
                                        .and(SysUserRoleTable.RoleId.eq(param.getRoleId()))
                                )
                ));
        queryWrapper.and(SysUserTable.UserName.like(param.getUserName()))
                .and(SysUserTable.PhoneNumber.like(param.getPhoneNumber()));
        log.info("查询条件：{}", queryWrapper.toSQL());
        return queryWrapper;
    }

    /**
     * 通过用户ID查询角色数量
     *
     * @param userId 用户ID
     * @return 结果
     */
    public List<Long> listRoleIdByUserId(Long userId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(SysUserRoleTable.RoleId)
                .from(SysUserRoleTable)
                .where(SysUserRoleTable.UserId.eq(userId));
        return this.listAs(queryWrapper, Long.class);
    }

    /**
     * 保存用户和角色信息关联
     *
     * @param userId  用户ID
     * @param roleIds 需要新增的角色数据ID
     */
    public void saveUserRole(Long userId, List<Long> roleIds) {
        // 新增用户与角色管理
        List<SysUserRole> list = new ArrayList<>();
        for (Long roleId : roleIds) {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        this.saveBatch(list, 100);
    }

    /**
     * 通过用户ID删除用户和角色关联
     * delete from sys_user_role where user_id=#{userId}
     *
     * @param userId 用户ID
     */
    public void removeUserRoleByUserId(Long userId) {
        QueryWrapper queryWrapper = query().where(SysUserRoleTable.UserId.eq(userId));
        this.remove(queryWrapper);
    }

    /**
     * 批量删除用户和角色关联
     * delete from sys_user_role where user_id in
     *
     * @param userIds 用户ID列表
     */
    public void removeUserRoleByUserIds(List<Long> userIds) {
        QueryWrapper queryWrapper = query().where(SysUserRoleTable.UserId.in(userIds));
        this.remove(queryWrapper);
    }
}
